package com.mioto.ld.communication.mqtt.protocol;

import cn.hutool.core.collection.CollUtil;
import com.mioto.ld.communication.mqtt.protocol.cache.ReportAttributeCache;
import com.mioto.ld.communication.mqtt.protocol.model.AlertLogCondition;
import com.mioto.ld.communication.mqtt.protocol.model.Message;
import com.mioto.ld.module.alert.model.AlertTrigger;
import com.mioto.ld.module.alert.model.LinkageTrigger;
import com.mioto.ld.module.device.model.Device;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @author mioto-qinxj
 * @date 2024/6/21
 * @desc
 */
@Slf4j
public class AttrReportTriggerHandler extends TriggerHandler{
    @Override
    protected void triggerProcess(Message message, Device device) {
        log.info("---------------告警触发器条件判断---------------");
        List<AlertTrigger> alertTriggers = alertTriggerService.findAttrTriggersByDeviceId(device.getId());
        //设备上报的属性
        Map<String,Object> reportAttr = ReportAttributeCache.getAttributes(device.getSn());
        //查询上报属性对应的id
        Map<Integer,String> customAttr = findDeviceAttributes(device.getProductId(),reportAttr);
        //如果系统未定义上报的属性，则不做任何处理
        if (CollUtil.isNotEmpty(customAttr)){
            boolean compareResult = false;
            Integer alertId = 0;
            //记录所有属性触发器对应的告警id
            Set<Integer> alertIds = new HashSet<>(2);
            //循环检查是否满足告警条件
            for (AlertTrigger alertTrigger : alertTriggers) {
                //同一个告警配置下，如果任意条件不满足，直接开始下次循环，直至下个告警配置
                if (alertTrigger.getAlertId().equals(alertId)  && !compareResult){
                    alertIds.remove(alertId);
                    continue;
                }
                log.info("start compare attribute trigger conditions - {}",alertTrigger.getTriggerCondition());
                compareResult =checkAttributeTriggerConditions(alertTrigger.getTriggerCondition()
                        ,alertTrigger.getTargetId(),customAttr,reportAttr);
                alertId = alertTrigger.getAlertId();
                if (!compareResult) {
                    alertIds.add(alertId);
                }
            }
            AlertLogCondition alertLogCondition = AlertLogCondition.builder().reportAttribute(reportAttr).build();
            //如果条件全部满足，保存告警日志
            if (compareResult){
                boolean saveResult =  saveAlertLog(device.getId(),alertId,(Date)reportAttr.get("reportTime")
                        ,alertLogCondition.toJsonStr());
                if (saveResult) {
                    deviceNotifyProcess.executeAlertNotify(alertId, device);
                }
            }else {
                //如果所有条件都不满足，则更新告警日志，变更告警恢复记录
                deviceAlertLogService.updateRecoveryData(device.getId(),alertIds
                        ,(Date)reportAttr.get("reportTime")
                        ,alertLogCondition.toJsonStr());
            }

            linkageTriggerProcess(device,reportAttr,customAttr);
        }
    }

    protected void linkageTriggerProcess(Device device,Map<String,Object> reportAttr,Map<Integer,String> customAttr) {
        log.info("---------------联动触发器条件判断---------------");
        List<LinkageTrigger> linkageTriggers = linkageTriggerService.findAttrTriggersByDeviceId(device.getId());
        boolean compareResult = false;
        int linkageId = 0;
        //循环检查是否满足告警条件
        for (LinkageTrigger linkageTrigger : linkageTriggers) {
            //同一个配置下，如果任意条件不满足，直接开始下次循环，直至下个配置
            if (linkageId == linkageTrigger.getLinkageId() && !compareResult){
                continue;
            }
            log.info("start compare attribute trigger conditions - {}",linkageTrigger.getTriggerCondition());
            compareResult =checkAttributeTriggerConditions(linkageTrigger.getTriggerCondition(),linkageTrigger.getTargetId(),customAttr,reportAttr);
            linkageId = linkageTrigger.getLinkageId();
        }
        //如果条件全部满足，执行动作
        if (compareResult){
            executeLinkageFunction(device, linkageId);
        }
    }

}
